import {useCallback, useState} from "react";
import {ConnectionHandler, useMutation} from "react-relay";
import {RecordSourceSelectorProxy,} from "relay-runtime";
import {useToast} from "customize-easy-ui-component";
import {
  useDeleteReportMutation$data,
} from "./__generated__/useDeleteReportMutation.graphql";
const graphql = require("babel-plugin-relay/macro");


const mutation = graphql`
  mutation useDeleteReportMutation(
    $repId: ID!
    $reason: String
  ) {
     deleteReport(repId: $repId,  reason: $reason)
     #必须在这里返回东西-受影响的GlobalID.node/Eadge;UserId;
  }
`;

/*
底下的 call:useCallback() 回调函数只能异步执行，无法用await 来等待同步化的。只能采用setResult和doing来修正和同步化处置。
返回的 result实际不是很有用的, relay直接替换Query关联数据。
返回的 doing, called, reset主要是提供同步机制，让用户等待后端的应答，不允许并发地搞其它的操作。
调用接口操作的组件可以通过 useEffect + Spinner 来保障接口的同步化，让用户务必要耐心等待后端应答后才能继续上路，避免异步并发可能导致逻辑混乱。
* */
export default function useDeleteReportMutation() {
  const [called, setCalled] =useState<boolean>(false);
  const [result, setResult] =useState<string>('');
  const [commit, doing] = useMutation(mutation);
  const toast = useToast();
  return {
    call:useCallback(
      (repId: string,reason: string, ispId:string) => {
        let disposable= commit({
          variables: {
            repId, reason
          },
          updater: (store: RecordSourceSelectorProxy, data) => {
            //这里 data 才有后端真实的回答
            const { deleteReport }= data as useDeleteReportMutation$data;
            if(!deleteReport)  return;
            sharedUpdater(store, ispId, repId);
          },
          optimisticUpdater: (store: RecordSourceSelectorProxy,data) => {
            //这里 data 还没有后端真实的回答？
            sharedUpdater(store, ispId, repId);
          },
          onCompleted: (response) => {
            const { deleteReport } = response as { deleteReport: boolean };
            setResult( '完成:'+deleteReport );
            toast({
              title: "后端回答了",
              subtitle: '应答deleteReport='+deleteReport,
              intent: "success"
            });
          },
         /* optimisticResponse: getOptimisticResponse(ispId, repId),*/
          onError: error => {
            setResult( '报错');
            toast({
              title: "后端回答了",
              subtitle: '删除＝'+error,
              intent: "error"
            });
          }
        });
        //必须放在commit函数之后的，才会doing逻辑=true生效,doing+called逻辑,保障同步化
        setCalled(true);
        return disposable;
      },
      [commit, toast]
    ),
    doing,
    result,
    called,
    reset: ()=>setCalled(false),
  };
}

function getOptimisticResponse(
    ispId: string,
    repId: string
): useDeleteReportMutation$data {
  return {
    deleteReport: true
  };
}
/**较为特别，俩层次的List底下的删除： findMeIsps[Isp] --> reps [Report] 删除某个报告。 有办法直接定位到删除节点。
 直接操作store模式。 还有一种 ConnectionHandler.getConnection 的方式会简单点。
 * */
function sharedUpdater(
    store: RecordSourceSelectorProxy,
    ispId: string,
    repId: string
) {
  const payload =store.get(ispId);
  if(!payload)  return;
  //这种方式，普通的【】数组列表也能做。就是要确定list链接于哪一个父辈对象{list:[]?}底下的，挂接父辈ID链接;根路径Query{}只能重查了;
  const payloadreps = payload.getLinkedRecord("reps");
  const payloadrepsedges = payloadreps?.getLinkedRecords("edges");
  const newarr=payloadrepsedges?.filter(function (edge, index, array) {
      const payloadnode =edge.getLinkedRecord("node");
      if (payloadnode?.getValue("id") === repId) {
        return false;
      }
      return true;
  });
  payloadreps?.setLinkedRecords(newarr,"edges");
}

